

#ifndef UC_GEPNT2D_H
#define UC_GEPNT2D_H

#include "zgevec2d.h"
#pragma pack (push, 8)

class UcGeMatrix2d;
class UcGeVector2d;
class UcGeLinearEnt2d;
class UcGeLine2d;

class
GE_DLLEXPIMPORT
UcGePoint2d
{
public:
    UcGePoint2d();
    UcGePoint2d(const UcGePoint2d& pnt);
    UcGePoint2d(double x, double y);

    static const   UcGePoint2d kOrigin;

    friend
    GE_DLLEXPIMPORT
    UcGePoint2d    operator *  (const UcGeMatrix2d& mat, const UcGePoint2d& pnt);
    UcGePoint2d&   setToProduct(const UcGeMatrix2d& mat, const UcGePoint2d& pnt);
    UcGePoint2d&   transformBy (const UcGeMatrix2d& leftSide);
    UcGePoint2d&   rotateBy    (double angle, const UcGePoint2d& wrtPoint
                                = UcGePoint2d::kOrigin);
    UcGePoint2d&   mirror      (const UcGeLine2d& line);
    UcGePoint2d&   scaleBy     (double scaleFactor, const UcGePoint2d& wrtPoint
                                = UcGePoint2d::kOrigin);

    UcGePoint2d    operator *  (double) const;
    friend
    UcGePoint2d    operator *  (double, const UcGePoint2d& scl);
    UcGePoint2d&   operator *= (double scl);
    UcGePoint2d    operator /  (double scl) const;
    UcGePoint2d&   operator /= (double scl);

    UcGePoint2d    operator +  (const UcGeVector2d& vec) const;
    UcGePoint2d&   operator += (const UcGeVector2d& vec);
    UcGePoint2d    operator -  (const UcGeVector2d& vec) const;
    UcGePoint2d&   operator -= (const UcGeVector2d& vec);
    UcGePoint2d&   setToSum    (const UcGePoint2d& pnt, const UcGeVector2d& vec);

    UcGeVector2d   operator -  (const UcGePoint2d& pnt) const;
    UcGeVector2d   asVector    () const;

    double         distanceTo  (const UcGePoint2d& pnt) const;

    bool operator == (const UcGePoint2d& pnt) const;
    bool operator != (const UcGePoint2d& pnt) const;
    bool isEqualTo   (const UcGePoint2d& pnt,
                                const UcGeTol& tol = UcGeContext::gTol) const;

    double         operator [] (unsigned int i) const;
    double&        operator [] (unsigned int idx);
    UcGePoint2d&   set         (double x, double y);

    double         x, y;
};

ZSOFT_FORCE_INLINE
UcGePoint2d::UcGePoint2d() : x(0.0), y(0.0)
{
}

ZSOFT_FORCE_INLINE
UcGePoint2d::UcGePoint2d(const UcGePoint2d& src) : x(src.x), y(src.y)
{
}

ZSOFT_FORCE_INLINE
UcGePoint2d::UcGePoint2d(double xx, double yy) : x(xx), y(yy)
{
}

ZSOFT_FORCE_INLINE bool
UcGePoint2d::operator == (const UcGePoint2d& p) const
{
    return this->isEqualTo(p);
}

ZSOFT_FORCE_INLINE bool
UcGePoint2d::operator != (const UcGePoint2d& p) const
{
    return !this->isEqualTo(p);
}

ZSOFT_FORCE_INLINE UcGePoint2d
UcGePoint2d::operator * (double val) const
{
    return UcGePoint2d(x*val, y*val);
}

ZSOFT_FORCE_INLINE UcGePoint2d
operator * (double val, const UcGePoint2d& p)
{
    return UcGePoint2d(p.x*val, p.y*val);
}

ZSOFT_FORCE_INLINE UcGePoint2d&
UcGePoint2d::operator *= (double val)
{
    x *= val;
    y *= val;
    return *this;
}

ZSOFT_FORCE_INLINE UcGePoint2d
UcGePoint2d::operator / (double val) const
{
    return UcGePoint2d (x/val, y/val);
}

ZSOFT_FORCE_INLINE UcGePoint2d&
UcGePoint2d::operator /= (double val)
{
    x /= val;
    y /= val;
    return *this;
}

ZSOFT_FORCE_INLINE UcGePoint2d
UcGePoint2d::operator + (const UcGeVector2d& v) const
{
    return UcGePoint2d(x + v.x, y + v.y);
}

ZSOFT_FORCE_INLINE UcGePoint2d&
UcGePoint2d::operator += (const UcGeVector2d& v)
{
    x += v.x;
    y += v.y;
    return *this;
}

ZSOFT_FORCE_INLINE UcGePoint2d
UcGePoint2d::operator - (const UcGeVector2d& v) const
{
    return UcGePoint2d(x - v.x, y - v.y);
}

ZSOFT_FORCE_INLINE UcGePoint2d&
UcGePoint2d::operator -= (const UcGeVector2d& v)
{
    x -= v.x;
    y -= v.y;
    return *this;
}

ZSOFT_FORCE_INLINE UcGeVector2d
UcGePoint2d::operator - (const UcGePoint2d& p) const
{
    return UcGeVector2d(x - p.x, y - p.y);
}

ZSOFT_FORCE_INLINE UcGeVector2d
UcGePoint2d::asVector() const
{
    return UcGeVector2d(x, y);
}

ZSOFT_FORCE_INLINE UcGePoint2d&
UcGePoint2d::set(double xx, double yy)
{
    x = xx;
    y = yy;
    return *this;
}

ZSOFT_FORCE_INLINE double
UcGePoint2d::operator [] (unsigned int i) const
{
    return *(&x+i);
}

ZSOFT_FORCE_INLINE double&
UcGePoint2d::operator [] (unsigned int i)
{
    return *(&x+i);
}

#define ZSOFT_UCGEPOINT2D_DEFINED
#include "zacarrayhelper.h"

#pragma pack (pop)
#endif
